package cn.zniot.so.application.service;

import cn.zniot.so.application.SessionManager;
import cn.zniot.so.application.constant.Constants;
import cn.zniot.so.application.data.Session;
import cn.zniot.so.application.util.PropertyUtil;
import cn.zniot.so.database.DBManager;
import cn.zniot.so.transport.asynpack.HBPacketD;
import cn.zniot.so.transport.asynpack.LogicCotrolPacketD;
import cn.zniot.so.transport.asynpack.Zniot2PacketC;

import org.apache.log4j.Logger;
import org.apache.mina.core.session.IoSession;

import java.util.Collection;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 心跳线程
 */
public class HeartBeatThread implements IService {
	private final Logger logger = Logger.getLogger(HeartBeatThread.class);
	private ScheduledExecutorService scheduledExecutorService;
	private LogicCotrolPacketD packet=null;
	private Zniot2PacketC zniot2PacketC = null;
	private  DBManager manager =null;
	
	public void wakeup() {
		
	}
	
	class HeartTraverse extends Thread {
        public void run() {
           while(true)
           {
               if (manager==null) {
                   manager=DBManager.getInstance();
               }
               LogicCotrolPacketD bean = null;
               while (!Session.m_iosession.isEmpty()) {
                   //异步入库
                   if ((bean = Session.m_iosession.poll()) != null) {
                        try {
                            boolean saveZniot2DB = manager.saveZniot2DB(bean);
                            if (!saveZniot2DB) {
                                if (logger.isInfoEnabled()) {
                                    logger.info("存储下线数据库失败");
                                }
                            }
                        } catch (Exception e) {
                            logger.error(e);
                        } finally {
                            bean = null;
                        }
                   }
               }
               while (!Session.tcpQueue.isEmpty()) {
                   //异步入库
                    if ((bean = Session.tcpQueue.poll()) != null) {
                        try {
                            boolean saveZniot2DB = manager.saveZniot2DB(bean);
                            if (!saveZniot2DB) {
                                // 手机客户端上线了，如果对应的盒子不在线就断开手机和服务器的连接
                                String imeiByIpPort = ControlSyncManager.getInstance()
                                        .getIpAndPortByimse(bean.getImei());
                                if (imeiByIpPort != null) {
                                    IoSession session = SessionManager.getInstance().getSession(
                                            imeiByIpPort);
                                    if (session != null) {
                                        if (zniot2PacketC == null) {
                                            zniot2PacketC = new Zniot2PacketC();
                                        }
                                        zniot2PacketC.setCode(Constants.CLIENT_DOWN);
                                        session.write(((Zniot2PacketC) zniot2PacketC));
                                    }
                                    SessionManager.getInstance().unregister(imeiByIpPort);// 去掉盒子注册信息
                                    if (logger.isDebugEnabled()) {
                                        logger.debug(imeiByIpPort
                                                + " unregister from sessionmanager");
                                    }
                                }
                            }
                        } catch (Exception e) {
                            logger.error(e);
                        } finally
                        {
                            bean = null;
                        }
                    }
               }
                try {
                    Thread.sleep(Constants.THREAD_MINUTE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
           }
        }
    }
	
	public void pause() {
	    
	}

	public void shutDown() {
	    if (scheduledExecutorService!=null) {
	        scheduledExecutorService.shutdown();
        }
	}

	@Override
	public void startUp() {
//		this.start();
	    if (logger.isDebugEnabled()) {
            logger.debug("HeartBeatThread begin running...");
        }
	    HeartTraverse t = new HeartTraverse();
        Thread thread = new Thread(t);
        thread.start();
	    scheduledExecutorService = Executors.newScheduledThreadPool(Constants.THREADNUM_LOGIC_SERVER);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                
                Collection<IoSession> sessions = SessionManager.getInstance().getAllSessions();
                if (logger.isDebugEnabled()) {
                    logger.debug("sessions size= "+sessions.size());
                }
                if (sessions.size()>0) {
                    for (IoSession session : sessions) {
                        if (session != null)
                        {
                            String ipAndPort;
                            try {
                                ipAndPort = session.getRemoteAddress().toString();
                            } catch (Exception e) {
                                ipAndPort = SessionManager.getInstance().getIpPortByIosession(session);
                                String imei = PropertyUtil.getInstance().getIMEIByIpPort(ipAndPort);
                                if (packet==null) {
									packet=new LogicCotrolPacketD();
								}
                                packet.setPdString(Constants.SINGE_NO);
                                packet.setImei(imei);
                                packet.setUid(ipAndPort);
                                SessionManager.getInstance().unregister(ipAndPort);// 去掉盒子注册信息
                                try {
                                    Session.m_iosession.offer(packet);
                                } catch (Exception ex) {
                                    //写入队列错误
                                    logger.error("写入队列错误--"+ex);
                                }
                                continue;
                            }   
                            session.write(HBPacketD.getInstance());
                        }
                    }
                }
            }
        }, 5, Constants.HEARTBEAT, TimeUnit.SECONDS);
	}

	@Override
	public byte getService() {
		return 0;
	}

}
